home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d7 / fsnip101.arc / FILESNIP.ASM < prev    next >
Assembly Source File  |  1990-06-09  |  40KB  |  1,329 lines

  1. page 60,132
  2. MASM
  3. ; This is a modification of the programme described below (SNIPPER).
  4. ; 0.0.1    gets all chars on lines between point 1 and point 2
  5. ; 0.0.2    allows the use of HOME and END keys to move around the screen.
  6. ; 0.0.3    allows hitting ESC key in filename prompt for entering
  7. ;    completely new file name.
  8. ; 0.0.4    fixed bug in ESC key during filename entry.  If esc hit and
  9. ;    then return, will exit without saving to file.  if ESC hit
  10. ;    then chars entered for new filename, will print to file. 
  11. ; 0.0.5    added new option when writing to file.  Entering F will now
  12. ;    strip out all multiple spaces and any pipes, as well as will
  13. ;    put 2 spaces after any punctuation.  Old write to file
  14. ;    (unformatted) is now option "U"
  15. ; 0.0.6    fixed problem with help box not displaying all options and
  16. ;    correctly formatting the box.
  17. ; 0.0.7    fixed help box display so that it is uses it's own character 
  18. ;    attributes, and restores original attribute upon exit.
  19. ; 0.0.8    Added colour to Help Box.  Unsure if will work with mono
  20. ; 0.0.9    gets filename from first 8 chars or from first char to period, 
  21. ;    of first line of highlight, + .RTT.   Refuses all chars which
  22. ;    filenames can not contain.
  23. ; 0.1.0    checks for mono display adapter.  if present, displays mono
  24. ;    help.
  25. ; 0.1.1    Modified display of copyright notice.
  26. ; 0.1.2 Added use of INS key when moving to top_left position.  Hitting
  27. ;    INS will move the cursor to the 34th column, which is the
  28. ;    standard starting space for file descriptions on PCB/ProDoor BBSs
  29. ; 0.1.3    Fixed problem with getting filename, and hitting ESC.  Now
  30. ;    resets filechar flag so that if used again after hitting esc, 
  31. ;    or entering a new filename, will now find new filename.  
  32. ;    Also, fills out full space for filename with 0H after each
  33. ;    filename.  Previously, if the new filename was shorter than
  34. ;    the last one entered, there would be residual chars.
  35. ; 0.1.4    Fixed problem with underscore as part of a filename.  Had
  36. ;    accidently included it in the list of chars not acceptable.
  37. ; 0.1.5    Fixed highlighting problem associated with reading filenames
  38. ;    of 8 chars + ext.
  39. ; 0.1.6    Program sends "fl filename.ext" to keyboard buffer, for file 
  40. ;    flagging on BBS.
  41. ; 0.1.7 Pruned program of unused or unnecessary functions relating to
  42. ;    SNIPPER
  43. ; 0.1.8    Extended total filename size to a maximum of 50 chars for
  44. ;    large paths.
  45. ; 0.1.9    Fixed problem with using the program multiple
  46. ;    times.  Wouldn't write more than one file nor would it spit
  47. ;    out more then "F" on the second use in the file flag section.
  48. ; 0.2.0    Reduced Maximum filename length to 12 places in anticipation of
  49. ;    the use of a path statement on the command line to be added in
  50. ;    an upcomming version.
  51. ; 0.2.1    Added use of pathname on command line.  Path statement will 
  52. ;    now be /P=path.  Command line must be eithe filesnip by itself
  53. ;    or filesnip rows,cols,/P=path
  54. ; 0.3.0    No modifications - Found no bugs
  55. ; 0.4.0    No modifications - Found no bugs
  56. ; 0.5.0    No modifications - Found no bugs
  57. ; 0.6.0    No modifications - Found no bugs
  58. ; 0.7.0    No modifications - Found no bugs
  59. ; 0.8.0    No modifications - Found no bugs
  60. ; 0.9.0    No modifications - Found no bugs
  61. ; 1.0.0    Initial Release - 6 June 1990
  62. ; 1.0.1 Made use of path statement flag on command line non-case
  63. ;    sensitive.
  64.  
  65.  
  66. ; SNIPPER is a resident utility which allows cutting out a portion
  67. ; of the screen.  The selected portion may be printed, written
  68. ; to disk or entered in the keyboard buffer.  Activate SNIPPER by
  69. ; pressing CTL-~, then position the cursor in the upper left corner of
  70. ; the window using the arrow keys.  Press CR to fix the first corner,
  71. ; then expand the window with arrow keys.  Finally, type "P" to print,
  72. ; "F" for disk file, "G" to retrieve or CR for a help menu.  Press ESC
  73. ; any time to exit SNIPPER.  When installing SNIPPER, use the optional
  74. ; parameters to expand it's internal buffer for displays (such as the
  75. ; EGA) containing more than the standard 25 rows and 80 columns.
  76. ;   SNIPPER  [rows,columns]
  77.  
  78. ;------------------------------------;
  79. ; BIOS_SEG IS THE ROM-BIOS DATA AREA ;
  80. ;------------------------------------;
  81. BIOS_SEG    SEGMENT    AT 0040H
  82.         ORG    004AH
  83. CRT_COLS    DB    ?        ;CURRENT NUMBER OF COLUMNS
  84.         ORG    0050H
  85. CURSOR_POSN    DW    8 DUP(?)    ;CURRENT CURSOR LOCATION
  86.         ORG    0062H
  87. ACTIVE_PAGE    DB    ?        ;ACTIVE PAGE FOR CGA AND EGA
  88.         ORG    0084H
  89. ROWS        DB    ?        ;LAST ROW NUMBER FOR EGA
  90. BIOS_SEG    ENDS
  91.  
  92. CSEG        SEGMENT
  93.         ASSUME    CS:CSEG,DS:NOTHING
  94.         ORG    0100H        ;BEGINNING FOR .COM PROGRAMS
  95. START:        
  96.                 JMP    INITIALIZE    ;INITIALIZATION CODE IS AT END
  97. ;--------------------------------;
  98. ; DATA AREA USED BY THIS PROGRAM ;
  99. ;--------------------------------;
  100. HOTKEY        EQU    29H        ;SCAN CODE FOR "~" KEY
  101. SHIFT_MASK    EQU    00000100B    ;MASK FOR CTL KEY
  102. COPYRIGHT     DB     17 DUP(20H),214,44 DUP(196),183
  103.         DB    13,10,17 DUP(20H),186,44 DUP(20H),186     
  104.         DB    10,13,17 DUP(20H),186," File-SNIP 1.0.1 (c) 1990 Mad Monk Software ",186
  105.         DB    10,13,17 DUP(20H),186,44 DUP(20H),186     
  106.         DB    10,13,17 DUP(20H),186,44 DUP(20H),186     
  107.         DB    10,13,17 DUP(20H),186,7,14 DUP(20H),"Hotkey is CTL-~",7,15 DUP(20H),186
  108.         DB    10,13,17 DUP(20H),186,44 DUP(20H),186     
  109.         DB     10,13,17 DUP(20H),211,44 DUP(196),189,13,10,"$",1AH     
  110. PROGRAMMER    DB    "File-SNIP:  Scott Penrose.  SNIPPER:  Tom Kihlken"
  111. INSTALLED_MSG    DB    "Already Installed",13,10,"$"
  112. BAD_DOS_MSG    DB    "Requires DOS 2.0+",13,10,"$"
  113. OLDINT09    DD    ?    ;OLD KEYBOARD BREAK INTERRUPT VECTOR
  114. OLDINT13    DD    ?    ;OLD BIOS DISK IO INTERRUPT VECTOR
  115. OLDINT16    DD    ?    ;OLD KEYBOARD INTERRUPT VECTOR
  116. OLDINT21    DD    ?    ;OLD DOS FUNCTION INTERRUPT VECTOR
  117. ERR_STAT    DB    ?    ;ERROR STATUS DURING FILE OUTPUT
  118. PATH_N_FILE    DB    128 DUP (0)
  119. FILE_PATH    DB    114 DUP (0)
  120. FILE_PROMPT    DB    "Enter Filename: "
  121. FILENAME    DB    "FILESNIP.RTT"    ;THE DEFAULT FILENAME
  122.         DB    2 DUP (0)    ;LEAVE ROOM FOR DRIVE AND PATH
  123. BUFF_START    EQU    OFFSET INITIALIZE
  124. BUFF_NEXT    DW      BUFF_START    ;POINTER TO NEXT KEY IN BUFFER
  125. BUFF_LAST    DW      BUFF_START    ;POINTER TO LAST KEY IN BUFFER
  126. BUFF_SIZE    EQU    25*(80+2)    ;ROOM FOR 25 ROWS OF 80 COLUMNS
  127. BUFF_END    DW    BUFF_START+BUFF_SIZE
  128. FILE_BUFF_START    EQU    OFFSET INITIALIZE+BUFF_SIZE
  129. FILE_BUFF_NEXT    DW      FILE_BUFF_START    ;POINTER TO NEXT KEY IN BUFFER
  130. FILE_BUFF_LAST    DW      FILE_BUFF_START    ;POINTER TO LAST KEY IN BUFFER
  131. FILE_BUFF_SIZE    EQU    12H          ;18 bytes
  132. FILE_BUFF_END    DW    FILE_BUFF_START+FILE_BUFF_SIZE
  133. TOP_LEFT    LABEL    WORD        ;FIRST CORNER OF WINDOW
  134. LEFT_SIDE    DB    0        ;COLUMN NUMBER OF LEFT SIDE
  135. TOP_ROW        DB    0        ;ROW NUMBER OF TOP SIDE
  136. BOT_RIGHT    LABEL    WORD        ;SECOND CORNER OF WINDOW
  137. RIGHT_SIDE    DB    ?        ;COLUMN NUMBER OR RIGHT SIDE
  138. BOT_ROW        DB    ?        ;ROW NUMBER OF BOTTOM
  139. SEND_CHAR    DW    ?        ;POINTER TO CHARACTER HANDLER
  140. FILE_SEND_CHAR    DW    ?        ;POINTER TO CHARACTER HANDLER
  141. HOME_END_HIT    LABEL    WORD        ;if=1 then home was hit
  142. HOME_END_LOOP    DB    0        ;IF=1, then first time in loop
  143. SEND_KEYS    DB    0        ;IF=1, USE KEYSTROKES FROM BUFFER
  144. FILE_SEND_KEYS    DB    0        ;IF=1, USE KEYSTROKES FROM BUFFER
  145. WRIT_FILE    DB    0        ;IF=1, NEED TO WRITE TO DISK
  146. BUSY_FLAGS    DB    0        ;BIT MASKED AS FOLLOWS:
  147.                     ; 1 - DOS IS ACTIVE
  148.                     ; 2 - BIOS IO IS ACTIVE
  149.                     ; 4 - SNIPPER IS ACTIVE
  150. DOS_STAT    DB    0        ;CURRENT DOS FUNCTION
  151. SPACE_FLAG    DB    0        ;Determine if space should be printed
  152. FILECHAR    DB    0        ;
  153. FILE_EXT    DB    0
  154. CHARS_ON_STACK    DB    0        ;How many chars have been printed
  155. PUNCT_FLAG     DB    0        ;was any punctuation found?
  156. HELP_MENU    DB    201,21 DUP(205),187
  157.         DB    186,"  F - File Formatted ",186
  158.         DB    186,"  P - Print          ",186
  159.         DB    186," Esc- Quit           ",186
  160.         DB    200,21 DUP(205),188
  161. HELP_MENU_ATTR1    DB    23 DUP(4EH)    ;ANSI menu
  162.         DB    23 DUP(4EH)
  163.         DB    23 DUP(4EH)
  164.         DB    23 DUP(4EH)
  165.         DB    23 DUP(4EH)
  166. HELP_MENU_ATTR2    DB    23 DUP(07H)    ;ASCII menu
  167.         DB    23 DUP(07H)
  168.         DB    23 DUP(07H)
  169.         DB    23 DUP(07H)
  170.         DB    23 DUP(07H)
  171.  
  172. ;------------------------------------------------------------------;
  173. ; SNIPPER BUILDS THE WINDOW AND ACCEPTS COMMANDS FROM THE KEYBOARD ;
  174. ;------------------------------------------------------------------;
  175. SNIPPER        PROC    NEAR
  176.         ASSUME    DS:CSEG, ES:BIOS_SEG
  177.         XOR    BX,BX        ;BX IS INCREMENT FOR ROW/COLUMN
  178. GET_KB_KEY1:
  179.         MOV    DX,TOP_LEFT    ;GET LOCATION OF FIRST CORNER
  180.         ADD    DH,BH        ;ADD IN THE ROW INCREMENT
  181.         ADD    DL,BL        ;ADD IN THE COLUMN INCREMENT
  182.         CMP    DL,0        ;AT LEFT EDGE OF SCREEN?
  183.         JGE    NOT_LEFT_EDGE
  184.         MOV    DL,CRT_COLS    ;JUMP TO THE RIGHT EDGE
  185.         DEC    DL
  186. NOT_LEFT_EDGE:
  187.         CMP    DL,CRT_COLS    ;AT RIGHT EDGE OF SCREEN YET?
  188.         JB    NOT_RIGHT_EDGE    ;IF NOT, KEEP MOVING RIGHT
  189.         XOR    DL,DL        ;IF YES, WRAP TO LEFT EDGE
  190. NOT_RIGHT_EDGE:
  191.         CMP    DH,0        ;AT TOP OF SCREEN YET?
  192.         JGE    NOT_AT_TOP
  193.         MOV    DH,ROWS        ;JUMP DOWN TO THE BOTTOM
  194. NOT_AT_TOP:
  195.         CMP    DH,ROWS        ;AT BOTTOM OF SCREEN?
  196.         JLE    NOT_AT_BOTTOM
  197.         XOR    DH,DH        ;JUMP BACK TO THE TOP
  198. NOT_AT_BOTTOM:
  199.         MOV    TOP_LEFT,DX    ;SAVE NEW CORNER LOCATION
  200.         CALL    REV_VIDEO    ;CHANGE IT TO REVERSE VIDEO
  201.         XOR    AH,AH        ;BIOS KEYBOARD INPUT
  202.         INT    16H        ;GET A KEYSTROKE
  203.         PUSH    AX
  204.         CALL    REV_VIDEO    ;PUT ATTRIBUTE BACK TO NORMAL
  205.         POP    AX
  206.         CMP    AH,1        ;IS IT ESCAPE?
  207.         JNE    NOT_ESC
  208.         RET            ;JUST RETURN TO EXIT
  209. NOT_ESC:
  210.         MOV    BX,0FF00H    ;INCREMENT TO SUBTRACT ONE ROW
  211.         CMP    AH,48H        ;IS IT UP ARROW?
  212.         JE    GET_KB_KEY1
  213.         MOV    BX,0100H    ;INCREMENT TO ADD ONE ROW
  214.         CMP    AH,50H        ;IS IT DOWN ARROW?
  215.         JE    GET_KB_KEY1
  216.         
  217.         MOV    BX,0001H    ;INCREMENT TO ADD ONE COLUMN
  218.         CMP    AH,4FH        ;IS IT END KEY?
  219.         JE    END_HIT        ;jump to END_hit
  220.         
  221.         MOV    BX,0001H    ;INCREMENT TO ADD ONE COLUMN
  222.         CMP    AH,52H        ;IS IT INS KEY?
  223.         JE    INS_HIT    ;jump to PLUS_hit
  224.  
  225.         MOV    BX,0001H    ;INCREMENT TO ADD ONE COLUMN
  226.         CMP    AH,4DH        ;IS IT RIGHT ARROW?
  227.         JE    GET_KB_KEY1
  228.         
  229.         MOV    BX,00FFH    ;INCREMENT TO SUBTRACT ONE COLUMN
  230.         CMP    AH,47H        ;Is it home key
  231.         JE    HOME_HIT    ;jump to home_hit
  232.  
  233.         MOV    BX,00FFH    ;INCREMENT TO SUBTRACT ONE COLUMN
  234.         CMP    AH,4BH        ;IS IT LEFT ARROW?
  235.         JNE    NOT_LEFT_ARROW
  236.         JMP    GET_KB_KEY1
  237. NOT_LEFT_ARROW:
  238.         XOR    BX,BX
  239.         CMP    AL,13        ;IS IT A CARRIAGE RETURN?
  240.         JNE    NOT_CR
  241.         MOV    DX,TOP_LEFT    ;A CARRIAGE RETURN WAS PRESSED
  242.         MOV    BOT_RIGHT,DX    ;INITIALIZE THE SECOND CORNER
  243.         CALL    REV_VIDEO    ;CHANGE IT BACK TO REVERSE VIDEO
  244.         JMP    SHORT GET_KB_KEY2
  245. NOT_CR:
  246.         JMP    GET_KB_KEY1    ;JUST GET ANOTHER KEY
  247. HOME_HIT:
  248.         MOV    DL,0        ;put cursor at beginning of line
  249.         MOV    BL,0        ;
  250.         PUSH    DX
  251.         MOV    DX,TOP_LEFT
  252.         MOV    DL,0H
  253.         MOV    TOP_LEFT,DX
  254.         POP    DX
  255.         JMP    GET_KB_KEY1    ;JUST GET ANOTHER KEY
  256. END_HIT:
  257.         MOV    BL,0H        ;put cursor at end of line.
  258.         MOV    DL,0H        ;
  259.         PUSH    DX
  260.         MOV    DX,TOP_LEFT
  261.         MOV    DL,4FH
  262.         MOV    TOP_LEFT,DX
  263.         POP    DX
  264.         JMP    GET_KB_KEY1    ;JUST GET ANOTHER KEY
  265. INS_HIT:
  266.         MOV    BL,0H        ;put cursor at 34th column
  267.         MOV    DL,0H        ;
  268.         PUSH    DX
  269.         MOV    DX,TOP_LEFT
  270.         MOV    DL,21H
  271.         MOV    TOP_LEFT,DX
  272.         POP    DX
  273.         JMP    GET_KB_KEY1    ;JUST GET ANOTHER KEY
  274. GET_KB_KEY2:
  275.         MOV    HOME_END_HIT,0000H    ;clear flag for home/end key
  276.         XOR    AH,AH
  277.         INT    16H        ;GET A KEYSTROKE
  278. GOT_KEY2:    MOV    DX,BOT_RIGHT
  279.         CMP    AH,48H        ;IS IT UP ARROW?
  280.         JNE    NEXT_1
  281.         JMP    SUB_ROW_1    ;SUBTRACT A ROW FROM WINDOW
  282. NEXT_1:
  283.         CMP    AH,50H        ;IS IT DOWN ARROW?
  284.         JNE    NEXT_2
  285.         JMP    ADD_ROW_1    ;ADD A ROW TO THE WINDOW
  286. NEXT_2:    
  287.         CMP    AH,4DH        ;IS IT RIGHT ARROW?
  288.         JNE    NEXT_3
  289.         JMP    ADD_COL        ;ADD A COLUMN TO THE WINDOW
  290. NEXT_3:
  291.         CMP    AH,4BH        ;IS IT LEFT ARROW?
  292.         JNE    NEXT_4
  293.         JMP    SUB_COL        ;SUBTRACT A COLUMN FROM WINDOW
  294. NEXT_4:
  295.         CMP    AH,47H        ;is it home key.
  296.         JNE    NEXT_5
  297.         MOV    HOME_END_HIT,0001H
  298.         MOV    HOME_END_LOOP,01H
  299.         JMP    SUB_COL    
  300. NEXT_5:
  301.         CMP    AH,4FH        ;is it end key?
  302.         JNE    NEXT_6
  303.         MOV    HOME_END_HIT,0100H
  304.         JMP    ADD_COL
  305. NEXT_6:
  306.         JMP    NOT_ARROW_KEY
  307. SUB_COL:
  308.         CMP    DH,TOP_ROW
  309.         JG    OK_GO_BACK
  310.         CMP    DL,LEFT_SIDE    ;DONT ERASE IT COMPLETELY
  311.         JLE    GET_KB_KEY2
  312. OK_GO_BACK:
  313.         CMP    DL,0        ;DONT ERASE IT COMPLETELY
  314.         JLE    GET_KB_KEY2
  315.         DEC    DL        ;SUBTRACT A COLUMN
  316.         MOV    RIGHT_SIDE,DL    ;SAVE NEW RIGHT SIDE COLUMN
  317.         INC    DL
  318. DONT_INC_DL:
  319.         JMP    SHORT COL_LOOP
  320. ADD_COL:
  321.         INC    DL        ;ADD A COLUMN
  322.         CMP    DL,CRT_COLS    ;AT RIGHT EDGE OF SCREEN?
  323.         JL    ADD_COL_1
  324.         JMP    GET_KB_KEY2    ;STOP WHEN SCREEN IS FILLED
  325. ADD_COL_1:
  326.         MOV    RIGHT_SIDE,DL    ;SAVE NEW RIGHT SIDE COLUMN
  327. COL_LOOP:
  328.         CMP    HOME_END_HIT,0001H
  329.         JZ    COL_LOOP_1
  330.         CMP    HOME_END_HIT,0100H
  331.         JZ    COL_LOOP_2
  332.         CALL    REV_VIDEO    ;REVERSE THIS CHARACTER
  333.         JMP    GET_KB_KEY2
  334. COL_LOOP_1:
  335.         CALL    REV_VIDEO    ;REVERSE THIS CHARACTER
  336.         DEC    DL
  337.         JMP    SUB_COL
  338. COL_LOOP_2:
  339.         CALL    REV_VIDEO    ;REVERSE THIS CHARACTER
  340.         JMP    ADD_COL
  341. SUB_ROW_1:
  342.         CMP    DH,TOP_ROW    ;AT TOP OF WINDOW?
  343.         JG    SUB_ROW_2
  344.         JMP    GET_KB_KEY2    ;DONT ERASE IT COMPLETELY
  345. SUB_ROW_2:
  346.         PUSH    DX
  347. SUB_ROW:
  348.         CALL    REV_VIDEO
  349.         DEC    DL        ;SUBTRACT A COLUMN
  350.         CMP    DL,0        ;DONT ERASE IT COMPLETELY
  351.         JL    SUB_ROW_PLUS
  352.         JMP    SUB_ROW
  353. SUB_ROW_PLUS:
  354.         POP    DX
  355.         PUSH    CX
  356.         MOV    CX,TOP_LEFT
  357.         INC    CH
  358.         CMP    CH,DH
  359.         JE    ON_SECOND_ROW
  360.         JMP    SUB_ROW_PLUS_1
  361. ON_SECOND_ROW:        
  362.         CMP    CL,DL
  363.         JLE    SUB_ROW_PLUS_1
  364.         MOV    DL,CL
  365.         MOV    BOT_RIGHT,DX
  366. SUB_ROW_PLUS_1:
  367.         POP    CX
  368.         DEC     DH
  369.         MOV    BOT_ROW,DH
  370.         PUSH    DX
  371. SUB_ROW_PLUS_2:
  372.         CMP    DL,79
  373.         JGE    AT_END
  374.         INC    DL
  375.         CALL    REV_VIDEO
  376.         JMP    SUB_ROW_PLUS_2
  377. AT_END:        
  378.         POP    DX
  379.         JMP    GET_KB_KEY2
  380.         
  381.         
  382. ADD_ROW_1:
  383.         CMP    DH,ROWS        ;AT BOTTOM OF SCREEN?
  384.         JL    ADD_ROW_1_1
  385.         JMP    GET_KB_KEY2    ;STOP WHEN SCREEN IS FILLED
  386. ADD_ROW_1_1:
  387.         PUSH    DX
  388. ADD_ROW:
  389.         CMP    DL,79
  390.         JZ    SKIP_INC
  391.         INC     DL
  392.         CALL    REV_VIDEO
  393. SKIP_INC:
  394.         CMP    DL,78
  395.         JG    ADD_ROW_PLUS
  396.         JMP     ADD_ROW
  397. ADD_ROW_PLUS:
  398.         POP    DX
  399.         CMP    DH,ROWS        ;AT BOTTOM OF SCREEN?
  400.         JL    NOT_BOT
  401.         JMP    GET_KB_KEY2    ;STOP WHEN SCREEN IS FILLED
  402. NOT_BOT:
  403.         INC    DH
  404.         MOV    BOT_ROW,DH
  405. ROW_LOOP:
  406.         CALL    REV_VIDEO    ;REVERSE THIS CHARACTER
  407.         DEC    DL        ;MOVE TO NEXT COLUMN
  408.         CMP    DL,0        ;AT LEFT EDGE YET?
  409.         JGE    ROW_LOOP    ;CONTINUE UNTIL AT LEFT EDGE
  410.         JMP    GET_KB_KEY2
  411. NOT_ARROW_KEY:
  412.         CMP    AH,19H        ;WAS IT THE "P" KEY?
  413.         JNE    NOT_P
  414.         MOV    SEND_CHAR,OFFSET PRINT_CHAR
  415.         JMP    FORMAT_OUTPUT
  416. NOT_P:
  417.         MOV    BUFF_NEXT,BUFF_START
  418.         MOV    BUFF_LAST,BUFF_START
  419.         MOV    FILE_BUFF_NEXT,FILE_BUFF_START
  420.         MOV    FILE_BUFF_LAST,FILE_BUFF_START
  421.         MOV    SEND_CHAR,OFFSET BUFF_CHAR
  422.         CMP    AH,21H        ;IS IT THE "F" KEY
  423.         JNE    NOT_F
  424.         MOV    WRIT_FILE,0
  425.         MOV    FILE_SEND_CHAR,OFFSET FILE_BUFF_CHAR
  426.         CALL    GET_FILENAME
  427.         CMP    WRIT_FILE,-1    ;WAS ESCAPE REQUESTED?
  428.         JE    ERASE_BOX
  429.         CALL    FORMAT_OUTPUT
  430.         MOV    WRIT_FILE,1
  431.         MOV    FILE_SEND_KEYS,01H
  432.         TEST    BUSY_FLAGS,00000011B     ;IS INT21 OR INT13 BUSY?
  433.         JNZ    RETURN        ;IF YES, WAIT TILL LATER
  434.         CALL    WRITE_TO_FILE    ;IF NOT, DO IT NOW
  435. RETURN:
  436.         RET
  437. NOT_F:
  438.         CMP    AH,1        ;IS IT ESCAPE?
  439.         JE    ERASE_BOX ;IF YES, ERASE BOX AND EXIT
  440.         CMP    AL,13        ;IS IT A CARRIAGE RETURN?
  441.         JE    DISPLAY_HELP    ;IF YES, DISPLAY HELP
  442.         JMP    GET_KB_KEY2    ;OTHERWISE JUST GET ANOTHER KEY
  443. ERASE_BOX:
  444.         MOV    SEND_CHAR,OFFSET RETURN
  445.         JMP    FORMAT_OUTPUT
  446. DISPLAY_HELP:
  447.         CALL    EXCHANGE_HELP    ;PUT UP THE HELP MENU
  448.         XOR    AH,AH
  449.         INT    16H        ;GET ANOTHER KEYSTROKE
  450.         PUSH    AX        ;SAVE THE KEYSTROKE
  451.         CALL    EXCHANGE_HELP    ;PULL DOWN THE HELP MENU
  452.         POP    AX        ;GET BACK THE KEYSTROKE
  453.         JMP    GOT_KEY2
  454. ;*********************************************************************
  455. REV_VIDEO:
  456.         CALL    READ_CHAR    ;READ CHARACTER AND ATTRIBUTE
  457.         MOV    BL,AH        ;SAVE ATTRIBUTE IN BL
  458.         AND    BL,10001000B    ;GET BLINK AND INTENSITY BITS
  459.         AND    AH,01110111B    ;NOW LOOK ONLY AT COLOR BITS
  460.         MOV    CL,4        ;ROTATE FOUR COUNTS
  461.         ROR    AH,CL        ;ROTATE FOREGROUND AND BACKGROUND
  462.         OR    BL,AH        ;PUT BACK BLINK AND INTENSITY BITS
  463.         CALL    DISPLAY_CHAR    ;WRITE CHARACTER AND ATTRIBUTE
  464.         RET
  465. ;*********************************************************************
  466. ;---------------------------------------------------------------------;
  467. ; Proceedure to read char off screen, and send to file formatted.
  468. ; 11-05-90  12:15am
  469. ;---------------------------------------------------------------------;
  470. FORMAT_OUTPUT:    
  471.         PUSH    AX
  472.         PUSH    BX
  473.         PUSH    CX
  474.         PUSH    DX
  475.         MOV    DX,TOP_LEFT    ;GET LOCATION OF FIRST CORNER
  476.         MOV    SPACE_FLAG,00H
  477.         MOV    PUNCT_FLAG,00H
  478.         MOV    CHARS_ON_STACK,00H
  479. READ_LOOP_NEW:
  480.         CALL    REV_VIDEO
  481.         CALL    READ_CHAR
  482.         CMP    AL,20H
  483.         JNE    READ_LOOP_NEW_1
  484.         JMP    WAS_SPACE
  485. READ_LOOP_NEW_1:
  486.         CMP    AL,7CH
  487.         JNE    NOT_PIPE
  488.         JMP    MOVE_TO_NEXT_CHAR
  489. NOT_PIPE:
  490.         CMP    AL,21H        ;is it a "!"
  491.         JNE    NOT_PIPE_1
  492.         JMP    PUNCT
  493. NOT_PIPE_1:
  494.         CMP    AL,2EH        ;is it a "."
  495.         JNE    NOT_PERIOD
  496.         JMP    PUNCT
  497. NOT_PERIOD:
  498.         CMP    AL,3FH        ;is it a "?"
  499.         JNE    NOT_QUESTION
  500.         JMP    PUNCT
  501. NOT_QUESTION:
  502.         CMP    AL,3AH        ;is it a ":"
  503.         JNE    NOT_COLON
  504.         JMP    PUNCT
  505. NOT_COLON:
  506.         CMP    AL,3BH        ;is it a ";"
  507.         JNE    NOT_SEMICOLON
  508.         JMP    PUNCT
  509. NOT_SEMICOLON:
  510. READ_NEW_1:
  511.         CMP    SPACE_FLAG,01
  512.         JE    SPACE_SET
  513.         CALL    SEND_CHAR
  514.         INC    CHARS_ON_STACK
  515. MOVE_TO_NEXT_CHAR:
  516.         CMP    DH,BOT_ROW
  517.         JE    LAST_LINE_NEW
  518.         INC    DL
  519.         CMP     DL,79
  520.         JG    MOVE_1
  521.         JMP    READ_LOOP_NEW
  522. MOVE_1:
  523.         CALL    CR_LF
  524.         MOV    CHARS_ON_STACK,00H
  525.         MOV    SPACE_FLAG,00H
  526.         MOV    PUNCT_FLAG,00H
  527.         INC    DH
  528.         MOV    DL,0
  529.         CMP    DH,BOT_ROW
  530.         JG    MOVE_3
  531.         JMP    READ_LOOP_NEW
  532. MOVE_3:
  533.         CALL    REV_VIDEO
  534. LAST_LINE_NEW:
  535.         INC     DL
  536.         CMP    DL,RIGHT_SIDE
  537.         JG    LAST_LINE_NEW_1
  538.         JMP     READ_LOOP_NEW
  539. LAST_LINE_NEW_1:
  540.         CALL    CR_LF
  541.         POP    DX
  542.         POP    CX
  543.         POP    BX
  544.         POP    AX
  545.         RET
  546. SPACE_SET:
  547.         CMP    CHARS_ON_STACK,0
  548.         JE    NO_PUNCT_FLAG
  549.         PUSH    AX
  550.         MOV    AX,0020H
  551.         CALL     SEND_CHAR
  552.         POP    AX
  553.         INC    CHARS_ON_STACK
  554.         CMP    PUNCT_FLAG,01H 
  555.         JNE    NO_PUNCT_FLAG
  556.         MOV    PUNCT_FLAG,00H
  557.         PUSH    AX
  558.         MOV    AX,0020H
  559.         CALL     SEND_CHAR
  560.         POP    AX
  561.         INC    CHARS_ON_STACK
  562.         CALL    SEND_CHAR
  563.         INC    CHARS_ON_STACK
  564.         MOV    SPACE_FLAG,00H
  565.         JMP    MOVE_TO_NEXT_CHAR
  566. NO_PUNCT_FLAG:
  567.         CALL     SEND_CHAR
  568.         INC    CHARS_ON_STACK
  569.         MOV    SPACE_FLAG,00H
  570.         JMP    MOVE_TO_NEXT_CHAR
  571. PUNCT:
  572.         CMP    CHARS_ON_STACK,0
  573.         JNE    PUNCT_1
  574.         JMP    READ_NEW_1
  575. PUNCT_1:
  576.         MOV    PUNCT_FLAG,01H
  577.         JMP    READ_NEW_1
  578. WAS_SPACE:
  579.         MOV    SPACE_FLAG,01H    
  580.         JMP    MOVE_TO_NEXT_CHAR
  581. ;*********************************************************************
  582. CR_LF:
  583.         MOV    AL,13
  584.         CALL    SEND_CHAR    ;SEND A CARRIAGE RETURN
  585.         MOV    AL,10
  586.         CALL    SEND_CHAR    ;SEND A LINE FEED
  587.         RET
  588. ;*********************************************************************
  589. DISPLAY_CHAR:
  590.         PUSH    BX        ;SAVE THE ATTRIBUTE
  591.         CALL    GET_CURS_ADDR    ;GET ADDRESS OF BIOS CURSOR
  592.         MOV    ES:[BX],DX    ;TELL BIOS WHERE THE CURSOR IS
  593.         POP    BX        ;GET BACK THE ATTRIBUTE
  594.         MOV    BH,ACTIVE_PAGE    ;GET ACTIVE PAGE
  595.         PUSH    CX        ;SAVE THE LOOP COUNT
  596.         MOV    CX,1        ;WRITE 1 CHARACTER
  597.         MOV    AH,9        ;WRITE CHARACTER AND ATTRIBUTE
  598.         INT    10H
  599.         POP    CX        ;RECOVER LOOP COUNT
  600.         RET            ;DONE WRITING THE CHARACTER
  601. ;*********************************************************************
  602. READ_CHAR:
  603.         CALL    GET_CURS_ADDR    ;GET ADDRESS OF BIOS CURSOR
  604.         MOV    ES:[BX],DX    ;TELL BIOS WHERE THE CURSOR IS
  605.         MOV    BH,ACTIVE_PAGE    ;GET ACTIVE PAGE
  606.         MOV    AH,8        ;BIOS FUNCTION TO READ CHARACTER
  607.         INT    10H        ;READ THE CHARACTER/ATTRIBUTE
  608.         RET
  609. ;*********************************************************************
  610. PRINT_CHAR:
  611.         PUSH    DX
  612.         XOR    AH,AH        ;USE FUNCTION 0
  613.         XOR    DX,DX        ;PRINTER NUMBER 0
  614.         INT    17H        ;BIOS PRINT CHARACTER FUNCTION
  615.         ROR    AH,1        ;LOOK AT BIT ZERO
  616.         JNC    PRINT_OK    ;DID A TIMEOUT OCCUR?
  617.         MOV    SEND_CHAR,OFFSET RETURN
  618. PRINT_OK:
  619.         POP    DX
  620.         RET            ;DONE PRINTING CHARACTER
  621. ;*********************************************************************
  622. BUFF_CHAR:
  623.         MOV    BX,BUFF_LAST    ;GET LOCATION OF LAST CHARACTER
  624.         MOV    [BX],AL        ;PUT THE CHARACTER IN BUFFER
  625.         INC    BX        ;ADVANCE THE POINTER
  626.         MOV    BUFF_LAST,BX    ;CHECK FOR BUFFER FULL
  627.         CMP    BX,BUFF_END    ;IS THE BUFFER FULL YET?
  628.         JNE    BUFF_OK        ;IF NOT, KEEP GOING
  629.         MOV    SEND_CHAR,OFFSET RETURN
  630. BUFF_OK:
  631.         RET            ;NOW ITS IN THE BUFFER
  632. ;*********************************************************************
  633. FILE_BUFF_CHAR:
  634.         MOV    BX,FILE_BUFF_LAST    ;GET LOCATION OF LAST CHARACTER
  635.         MOV    [BX],AL        ;PUT THE CHARACTER IN BUFFER
  636.         INC    BX        ;ADVANCE THE POINTER
  637.         MOV    FILE_BUFF_LAST,BX    ;CHECK FOR BUFFER FULL
  638.         CMP    BX,FILE_BUFF_END    ;IS THE BUFFER FULL YET?
  639.         JNE    FILE_BUFF_OK        ;IF NOT, KEEP GOING
  640.         MOV    FILE_SEND_CHAR,OFFSET RETURN
  641. FILE_BUFF_OK:
  642.         RET            ;NOW ITS IN THE BUFFER
  643. ;*********************************************************************
  644. GET_CURS_ADDR:
  645.         MOV    BL,ACTIVE_PAGE    ;GET THE CURRENT PAGE NUMBER
  646.         XOR    BH,BH        ;CONVERT TO A WORD OFFSET
  647.         SHL    BX,1        ;TIMES TWO FOR A WORD
  648.         ADD    BX,OFFSET CURSOR_POSN ;ADD IN BASE ADDRESS
  649.         RET
  650. ;*********************************************************************
  651. EXCHANGE_HELP:
  652.         XOR    DX,DX        ;START AT TOP LEFT CORNER
  653.         PUSH    DI
  654.         LEA    SI,HELP_MENU
  655.         MOV    AH,15
  656.         INT    10H
  657.         CMP    AL,7
  658.         JE    MONO_HELP
  659.         LEA    DI,HELP_MENU_ATTR1
  660.         JMP    EXCHANGE_LOOP
  661. MONO_HELP:
  662.         LEA    DI,HELP_MENU_ATTR2
  663. EXCHANGE_LOOP:
  664.         CMP    DL,23        ;AT LAST COLUMN IN THIS ROW YET?
  665.         JL    SWAP_CHAR
  666.         XOR    DL,DL        ;BACK TO FIRST COLUMN
  667.         INC    DH        ;DO THE NEXT ROW
  668.         CMP    DH,5        ;AT LAST ROW YET?
  669.         JL    SWAP_CHAR    ;QUIT WHEN LAST ROW IS DONE
  670.         POP    DI
  671.         RET
  672. SWAP_CHAR:
  673.         CALL    READ_CHAR    ;READ CHARACTER AT THIS POSITION
  674.         XCHG    AL,CS:[SI]    ;SWAP WITH THE HELP TEXT
  675.         XCHG    AH,CS:[DI]    ;SWAP WITH THE HELP TEXT
  676.         MOV    BL,AH        ;ATTRIBUTE IS THE SAME
  677.         CALL    DISPLAY_CHAR    ;PUT NEW CHARACTER ON SCREEN
  678.         INC    DL        ;POINT TO NEXT POSITION
  679.         INC    SI
  680.         INC    DI
  681.         JMP EXCHANGE_LOOP
  682. ;*********************************************************************
  683. TEST_FILENAME_CHAR:
  684.         CMP    AL,2EH
  685.         JE    FILECHAR_1
  686.         CMP    AL,20H
  687.         JLE    FILECHAR_1
  688.         CMP    AL,22H
  689.         JE    FILECHAR_1
  690.         CMP    AL,25H
  691.         JE    FILECHAR_1
  692.         CMP    AL,2AH
  693.         JE    FILECHAR_1
  694.         CMP    AL,2BH
  695.         JE    FILECHAR_1
  696.         CMP    AL,2CH
  697.         JE    FILECHAR_1
  698.         CMP    AL,2FH
  699.         JE    FILECHAR_1
  700.         CMP    AL,3AH
  701.         JE    FILECHAR_1
  702.         CMP    AL,3BH
  703.         JE    FILECHAR_1
  704.         CMP    AL,3CH
  705.         JE    FILECHAR_1
  706.         CMP    AL,3DH
  707.         JE    FILECHAR_1
  708.         CMP    AL,3EH
  709.         JE    FILECHAR_1
  710.         CMP    AL,7FH
  711.         JGE    FILECHAR_1
  712.         CMP    AL,5BH
  713.         JE    FILECHAR_1
  714.         CMP    AL,5CH
  715.         JE    FILECHAR_1
  716.         CMP    AL,5DH
  717.         JE    FILECHAR_1
  718.         CMP    AL,5EH
  719.         JE    FILECHAR_1
  720.         CMP    AL,60H
  721.         JE    FILECHAR_1
  722.         CMP    FILE_EXT,00H
  723.         JE    NOT_EXTEN
  724.         CMP    CL,04H
  725.         JE    FILECHAR_1
  726.         RET
  727. NOT_EXTEN:
  728.         CMP    CL,08H
  729.         JE    FILECHAR_1
  730.         RET
  731. FILECHAR_1:
  732.         MOV    FILECHAR,01
  733.         RET
  734. GET_FILENAME:
  735.         PUSH    BX
  736.         PUSH    AX
  737.         MOV    AX,0046H
  738.         CALL    FILE_SEND_CHAR
  739.         MOV    AX,004CH
  740.         CALL    FILE_SEND_CHAR
  741.         MOV    AX,0020H
  742.         CALL    FILE_SEND_CHAR
  743.         POP    AX
  744.         PUSH    DI
  745.         PUSH    SI
  746.         MOV    FILE_EXT,00H
  747.         MOV    FILECHAR,00H
  748.         PUSH    DX
  749.         PUSH    CX
  750.         MOV    CL,00H
  751.         MOV    DX,TOP_LEFT
  752.         MOV    DL,0
  753.         LEA    SI,FILENAME
  754. GET_FILENAME_1:
  755.         CALL    READ_CHAR
  756.         CALL    TEST_FILENAME_CHAR
  757.         CMP    FILECHAR,00H
  758.         JNE    END_OF_FILENAME_1
  759.         CMP    FILE_EXT,00H
  760.         JNE    FILE_EXTEN
  761.         MOV    CS:[SI],AL
  762.         INC    SI
  763. FILE_EXTEN:
  764.         CALL    FILE_SEND_CHAR
  765.         INC    DL
  766.         INC    CL
  767.         JMP    GET_FILENAME_1
  768. END_OF_FILENAME_1:
  769.         CMP    CL,0
  770.         JE     END_OF_FILENAME_A
  771.         CMP    FILE_EXT,01H
  772.         JE    AT_END_OF_FILENAME
  773.         MOV    FILECHAR,00H
  774.         MOV    FILE_EXT,01H
  775.         JMP    FILE_EXTEN
  776. AT_END_OF_FILENAME:
  777.         MOV    AL,0AH
  778.         CALL    FILE_SEND_CHAR
  779.         MOV    AL,0DH
  780.         CALL    FILE_SEND_CHAR
  781.         MOV    AL,2EH
  782.         MOV    CS:[SI],AL
  783.         INC    SI
  784.         MOV    AL,52H
  785.         MOV    CS:[SI],AL
  786.         INC    SI
  787.         MOV    AL,54H
  788.         MOV    CS:[SI],AL
  789.         INC    SI
  790.         MOV    AL,54H
  791.         MOV    CS:[SI],AL
  792.         INC    SI
  793. FILL_TO_END:
  794.         CMP    CL,0DH
  795. ;        CMP    CL,18H
  796.         JE    END_OF_FILENAME_A
  797.         MOV    AL,0H
  798.         MOV    CS:[SI],AL
  799.         INC    CL
  800.         INC    SI
  801.         JMP    FILL_TO_END
  802. END_OF_FILENAME_A:
  803.         POP    CX
  804.         POP    DX
  805.         LEA    SI,FILE_PROMPT    ;POINT TO THE PROMPT FOR SOURCE
  806.         XOR    DI,DI        ;USE THE PSP FOR BUFFER
  807.         XOR    DX,DX        ;PUT PROMPT AT TOP LEFT CORNER
  808.         MOV    CX,29        ;USE MAX OF 40 CHARACTERS
  809.         POP    BX
  810. DISPLAY_PROMPT:
  811.         PUSH    CX        ;SAVE LOOP COUNT
  812.         CALL    READ_CHAR    ;GET CHARACTER ON THIS LINE
  813.         MOV    CS:[DI],AX    ;STORE IT IN THE PSP
  814.         INC    DI        ;ADD TWO FOR NEXT CHARACTER
  815.         INC    DI
  816.         MOV    AL,CS:[SI]    ;GET NEXT PROMPT CHARACTER
  817.         INC    SI        ;NEXT CHARACTER IN PROMPT
  818.         MOV    BL,47H        ;ATTRIBUTE FOR PROMPT
  819.         CALL    DISPLAY_CHAR    ;PUT UP THE PROMPT CHARACTER
  820.         INC    DL        ;POINT TO NEXT COLUMN
  821.         POP    CX        ;GET BACK LOOP COUNT
  822.         LOOP    DISPLAY_PROMPT    ;ENTIRE PROMPT AND FILENAME
  823. FIND_LAST_LETTER:
  824.         DEC    SI        ;BACKUP TO LAST LETTER
  825.         DEC    DL        ;BACKUP TO LAST COLUMN
  826.         CMP    BYTE PTR [SI],0    ;IS THIS A LETTER?
  827.         JE    FIND_LAST_LETTER;BACKUP UNTILL A LETTER IS FOUND
  828.         INC    DL        ;PUT BLINKING BOX AT LAST LETTER
  829. READ_KB:
  830.         MOV    AL,219        ;ASCII FOR BOX CHARACTER
  831.         MOV    BL,47H+80H    ;MAKE IT A BLINKING BOX CHARACTER
  832.         CALL    DISPLAY_CHAR    ;WRITE THE BLINKING BOX
  833.         XOR    AH,AH        ;FUNCTIO 0 TO GET NEXT KEY
  834.         INT    16H        ;BIOS KEYBOARD INPUT
  835.         CMP    AL,13        ;IS IT A CARRIAGE RETURN?
  836.         JE    ERASE_PROMPT
  837.         CMP    AL,8        ;IS IT A BACKSPACE?
  838.         JE    BACK_SPACE
  839.         CMP    AH,1        ;IS IT ESCAPE?
  840.         JNE    READ_KBDRD_2
  841.         MOV    WRIT_FILE,-1    ;INDICATE ESCAPE IS REQUESTED
  842. READ_KBDRD_1:
  843.         CMP    DL,16        ;AT BEGINNING OF LINE?
  844.         JLE    READ_KB        ;IF YES, CAN'T BACKUP FROM HERE
  845.         MOV    AL,0        ;WRITE A NORMAL BLANK (ASCII 0)
  846.         MOV    BL,47H        ;ATTRIBUTE FOR FILENAME
  847.         CALL    DISPLAY_CHAR    ;WRITE THE LETTER
  848.         DEC    DL        ;BACKUP THE CURSOR
  849.         JMP    READ_KBDRD_1
  850. READ_KBDRD_2:
  851.         CMP    AL,"."        ;IS IT A VALID LETTER?
  852.         JL    READ_KB
  853.         CMP    AL,"z"        ;IS IT A VALID LETTER?
  854.         JG    READ_KB
  855.         CMP    DL,28        ;ONLY ALLOW 40 CHARACTERS
  856.         JGE    READ_KB
  857. TTY_KEY:
  858.  
  859.         MOV    WRIT_FILE,0    ;FIX ESCAPE HIT THEN CHARS.
  860.         MOV    BL,47H        ;ATTRIBUTE FOR FILENAME
  861.         CALL    DISPLAY_CHAR    ;WRITE THE LETTER
  862.         INC    DL        ;MOVE TO NEXT COLUMN
  863.         JMP    READ_KB        ;GET ANOTHER KEYSTROKE
  864. BACK_SPACE:
  865.         CMP    DL,16        ;AT BEGINNING OF LINE?
  866.         JLE    READ_KB        ;IF YES, CAN'T BACKUP FROM HERE
  867.         MOV    AL,0        ;WRITE A NORMAL BLANK (ASCII 0)
  868.         MOV    BL,47H        ;ATTRIBUTE FOR FILENAME
  869.         CALL    DISPLAY_CHAR    ;WRITE THE LETTER
  870.         DEC    DL        ;BACKUP THE CURSOR
  871.         JMP    READ_KB        ;THEN GET THE NEXT KEY
  872. ESC_RET:
  873.         MOV    WRIT_FILE,-1    ;INDICATE ESCAPE IS REQUESTED
  874. ERASE_PROMPT:
  875.         XOR    AL,AL        ;GET RID OF THE CURSOR
  876.         CALL    DISPLAY_CHAR    ;WRITE THE LETTER
  877.         LEA    DI,FILE_PROMPT    ;COPY TO FILENAME
  878.         XOR    SI,SI        ;COPY FROM PSP
  879.         XOR    DX,DX        ;PROMPT IS AT ROW ZERO
  880.         MOV    CX,29        ;COPY ALL 40 CHARACTERS
  881. ERASE_LOOP:
  882.         CALL    READ_CHAR    ;GET CHARACTER ON THIS LINE
  883.         MOV    CS:[DI],AL    ;PUT IN BACK IN MEMORY
  884.         INC    DI
  885.         MOV    AX,CS:[SI]    ;GET THE ORIGINAL CHARACTER BACK
  886.         MOV    BL,AH        ;PUT ATTRIBUTE INTO BL
  887.         INC    SI
  888.         INC    SI
  889.         CALL    DISPLAY_CHAR    ;WRITE ORIGINAL CHARACTER
  890.         INC    DL        ;MOVE TO NEXT COLUMN
  891.         LOOP    ERASE_LOOP    ;ERASE THE ENTIRE PROMPT
  892.         POP    SI
  893.         POP    DI
  894.         RET
  895. SNIPPER        ENDP
  896.  
  897. ;---------------------------------------------------------------------;
  898. ; THIS COPIES THE BUFFER CONTENTS TO A FILE. IT SHOULD ONLY BE CALLED ;
  899. ; WHEN DOS IS IN A STABLE AND REENTRANT CONDITION.                    ;
  900. ;---------------------------------------------------------------------;
  901. WRITE_TO_FILE    PROC    NEAR
  902.         ASSUME    DS:NOTHING, ES:NOTHING
  903.         MOV    WRIT_FILE,0    ;TURN OFF REQUEST FLAG
  904.         PUSH    AX        ;MUST PRESERVE ALL REGISTERS
  905.         PUSH    BX
  906.         PUSH    CX
  907.         PUSH    DX
  908.         PUSH    DS
  909.         PUSH    ES
  910.         PUSH    CS
  911.         POP    DS
  912.         ASSUME    DS:CSEG        ;DS POINTS TO OUR CODE SEGMENT
  913.              MOV    AX,3524H    ;GET DOS CRITICAL ERROR VECTOR
  914.         INT    21H        ;DOS FUNCTION TO GET VECTOR
  915.         PUSH    BX        ;SAVE OLD VECTOR ON STACK
  916.         PUSH    ES
  917. ; REPLACE THE DOS SEVERE ERROR INTERRUPT WITH OUR OWN ROUTINE.
  918.         MOV    DX,OFFSET NEWINT24
  919.         MOV    AX,2524H    ;SETUP TO CHANGE INT 24h VECTOR
  920.         INT    21H        ;CHANGE DOS SEVERE ERROR VECTOR
  921.         LEA    SI,PATH_N_FILE
  922. PATH_N_FILE_LOOP:
  923.         CMP    BYTE PTR[SI],0
  924.         JE    PNFL_DONE
  925.         MOV    BYTE PTR[SI],0
  926.         INC    SI
  927.         JMP    PATH_N_FILE_LOOP
  928. PNFL_DONE:
  929.         LEA    DI,PATH_N_FILE
  930.         LEA    SI,FILE_PATH
  931. TRANSFER_PATH_N_FILE:
  932.         CMP    BYTE PTR[SI],0
  933.         JE    TPNF_DONE
  934.         PUSH    BX
  935.         MOV    BL,[SI]
  936.         MOV    [DI],BL
  937.         POP    BX
  938.         INC    SI
  939.         INC    DI
  940.         JMP     TRANSFER_PATH_N_FILE
  941. TPNF_DONE:
  942.         LEA    SI,FILENAME
  943. ADD_FILENAME_LOOP:
  944.         CMP    BYTE PTR[SI],0
  945.         JE    AFL_DONE
  946.         PUSH    BX
  947.         MOV    BL,[SI]
  948.         MOV    [DI],BL
  949.         POP    BX
  950.         INC    SI
  951.         INC    DI
  952.         JMP    ADD_FILENAME_LOOP
  953. AFL_DONE:
  954.         MOV    DX,OFFSET PATH_N_FILE    ;POINT TO FILENAME
  955. ;        MOV    DX,OFFSET FILENAME ;POINT TO FILENAME
  956. ; FIRST TRY TO OPEN THE FILE.  IF DOS RETURNS WITH THE CARRY FLAG SET,
  957. ; THE FILE DIDN'T EXIST AND WE MUST CREATE IT.  ONCE THE FILE IS OPENED,
  958. ; ADVANCE THE FILE POINTER TO THE END OF FILE TO APPEND.
  959.         MOV    AX,3D02H    ;DOS FUNCTION TO OPEN FILE
  960.         INT    21H        ;DOS WILL RETURN WITH CARRY FLAG
  961.         JC    FILE_NOT_FOUND    ;SET IF FILE DOESN'T EXIST.
  962.         MOV    BX,AX        ;KEEP HANDLE IN BX ALSO
  963.         XOR    CX,CX        ;MOVE DOS FILE POINTER TO THE
  964.         XOR    DX,DX        ;END OF THE FILE. THIS LETS US
  965.         MOV    AX,4202H    ;APPEND THIS TO AN EXISTING FILE
  966.         INT    21H        ;DOS FUNCTION TO MOVE POINTER
  967.         JNC    WRITE_FILE    ;IF NO ERROR, CONTINUE TO WRITE
  968. DOS_ERROR:
  969.         CMP    ERR_STAT,0    ;DID A SEVERE ERROR OCCUR?
  970.         JNE    REP_VECTOR    ;IF SEVERE ERROR, JUST QUIT
  971.         JMP    SHORT CLOSE_FILE;JUST CLOSE THE FILE
  972.  
  973. FILE_NOT_FOUND:    CMP    ERR_STAT,0    ;DID A SEVERE ERROR OCCUR?
  974.         JNE    REP_VECTOR    ;IF SEVERE ERROR, JUST QUIT
  975.         MOV    CX,0020H    ;ATTRIBUTE FOR NEW FILE
  976.         MOV    AH,3CH        ;CREATE FILE FOR WRITING
  977.         INT    21H        ;DOS FUNCTION TO CREATE FILE
  978.         JC    DOS_ERROR       ;ON ANY ERROR, TAKE JUMP
  979.         MOV    BX,AX        ;SAVE HANDLE IN BX
  980. WRITE_FILE:     MOV    DX,BUFF_START    ;POINT TO BUFFER
  981.         MOV    CX,BUFF_LAST    ;GET BUFFER POINTER
  982.         SUB    CX,DX        ;NUMBER OF CHARS IN BUFFER
  983.         MOV    AH,40H        ;DOS WRITE TO A DEVICE FUNCTION
  984.         INT    21H        ;WRITE TO THE FILE
  985. CLOSE_FILE:
  986.         MOV    AH,3EH        ;DOS FUNCTION TO CLOSE THE FILE
  987.         INT    21H
  988. REP_VECTOR:
  989.         POP    DS        ;GET INT 24H VECTOR FROM STACK
  990.         POP    DX
  991.         MOV    AX,2524H    ;RESTORE CRITICAL ERROR VECTOR
  992.         INT    21H        ;DOS FUNCTION TO CHANGE VECTOR
  993.         POP    ES        ;FINALLY RESTORE ALL REGISTERS
  994.         POP    DS
  995.         POP    DX
  996.         POP    CX
  997.         POP    BX
  998.         POP    AX
  999.         RET            ;FINISHED WRITING TO DISK
  1000. WRITE_TO_FILE    ENDP
  1001. ;---------------------------------------------------------------------;
  1002. ; INTERRUPT 09 ROUTINE.  WATCH FOR TRIGGER KEY TO POP UP.
  1003. ;---------------------------------------------------------------------;
  1004. NEWINT09    PROC    FAR
  1005.         ASSUME    DS:NOTHING, ES:NOTHING
  1006.         STI            ;ALLOW OTHER INTERRUPTS
  1007.         PUSH    AX        ;MUST SAVE PROCESSOR STATE
  1008.         IN    AL,60H        ;GET THE SCAN CODE
  1009.         CMP    AL,HOTKEY    ;IS IT THE HOT KEY?
  1010.         JE    TRIGGER        ;IF YES, CHECK THE MASK
  1011. INT09_EXIT:    POP    AX        ;RESTORE THE PROCESSOR STATE
  1012.         JMP    OLDINT09    ;CONTINUE WITH ROM ROUTINE
  1013.  
  1014. TRIGGER:    MOV    AH,2        ;GET KEYBOARD STATUS
  1015.         INT    16H        ;BIOS KEYBOARD SERVICE
  1016.  
  1017.         AND    AL,0FH        ;Take lower four bits
  1018.         CMP    AL,SHIFT_MASK    ;IS CTL KEY DOWN?
  1019.         JNZ    INT09_EXIT    ;IF NOT, IGNORE IT
  1020.         TEST    BUSY_FLAGS,00000100B ;IS SNIPPER ALREADY ACTIVE?
  1021.         JNZ    INT09_EXIT    ;IF ACTIVE, THEN EXIT
  1022.         OR    BUSY_FLAGS,00000100B ;ITS ACTIVE NOW
  1023.         PUSHF
  1024.         CALL    OLDINT09    ;LET ROM PROCESS THE KEY
  1025.         PUSH    BX        ;MUST PRESERVE ALL REGISTERS
  1026.         PUSH    CX
  1027.         PUSH    DX
  1028.         PUSH    BP
  1029.         PUSH    SI
  1030.         PUSH    DI
  1031.         PUSH    DS
  1032.         PUSH    ES
  1033.         PUSH    CS
  1034.         POP    DS        ;SET DS TO CSEG
  1035.         MOV    AX,BIOS_SEG    ;ES POINTS TO BIOS DATA AREA
  1036.         MOV    ES,AX
  1037.         ASSUME    DS:CSEG, ES:BIOS_SEG
  1038.         CALL    GET_CURS_ADDR    ;CURSOR ADDRESS FOR THIS PAGE
  1039.         PUSH    ES:[BX]        ;SAVE THE CURSOR LOCATION
  1040.         CALL    SNIPPER        ;DO THE WINDOW
  1041.         CALL    GET_CURS_ADDR    ;CURS0R ADDRESS FOR THIS PAGE
  1042.         POP    ES:[BX]        ;GET BACK CURSOR  POSITION
  1043.         AND    BUSY_FLAGS,11111011B  ;SNIPPER IS NOT ACTIVE
  1044.         POP    ES        ;RESTORE ALL REGISTERS
  1045.         POP    DS
  1046.         POP    DI
  1047.         POP    SI
  1048.         POP    BP
  1049.         POP    DX
  1050.         POP    CX
  1051.         POP    BX
  1052.         POP    AX
  1053.         IRET            ;NOW WERE ALL DONE
  1054. NEWINT09    ENDP
  1055. ;---------------------------------------------------------------------;
  1056. ; INTERRUPT 13 ROUTINE. SET BIOS BUST BIT                             ;
  1057. ;---------------------------------------------------------------------;
  1058. NEWINT13    PROC    FAR
  1059.         ASSUME    DS:NOTHING, ES:NOTHING
  1060.         OR    BUSY_FLAGS,00000010B    ;SET BIOS BUSY BIT
  1061.         PUSHF
  1062.         CALL    OLDINT13    ;DO THE BIOS FUNCTION
  1063.         PUSHF            ;SAVE RESULT FLAGS
  1064.         AND    BUSY_FLAGS,11111101B    ;CLEAR BIOS BUSY BIT
  1065.         POPF            ;GET BACK RESULT FLAGS
  1066.         STI            ;MUST RETURN WITH INTERUPTS ON
  1067.         RET    2        ;RETURN BIOS RESULT FLAGS
  1068. NEWINT13    ENDP
  1069. ;---------------------------------------------------------------------;
  1070. ; INTERRUPT 16 ROUTINE. INSERT KEYSTROKES FROM BUFFER                 ;
  1071. ;---------------------------------------------------------------------;
  1072. NEWINT16    PROC    FAR
  1073.         ASSUME    DS:NOTHING, ES:NOTHING
  1074.         PUSH    BX
  1075.         CMP    SEND_KEYS,1    ;SENDING KEYS FROM BUFFER?
  1076.         JE    INSERT_KEY    ;IF YES, THEN GET NEXT ONE
  1077.         CMP    FILE_SEND_KEYS,1    ;SENDING KEYS FROM BUFFER?
  1078.         JE    FILE_INSERT_KEY    ;IF YES, THEN GET NEXT ONE
  1079.         CMP    WRIT_FILE,1    ;ANYTHING TO WRITE TO DISK?
  1080.         JE    CHECK_DOS_STAT    ;IF YES, THIS IS THE TIME
  1081. BIOS_KB:
  1082.         POP    BX
  1083.         JMP    OLDINT16    ;JUST DO NORMAL KB ROUTINE
  1084. CHECK_DOS_STAT:
  1085.         CMP    DOS_STAT,0AH    ;DOING READ STRING?
  1086.         JE    BEGIN_NOW    ;IF YES, ITS SAFE TO BEGIN
  1087.         CMP    DOS_STAT,8    ;DOING KEYBOARD INPUT?
  1088.         JNE    BIOS_KB        ;IF YES, ITS SAFE TO BEGIN
  1089. BEGIN_NOW:
  1090.         STI            ;GET INTERRUPTS BACK ON
  1091.         CALL    WRITE_TO_FILE    ;EMPTY THE BUFFER
  1092.         JMP    BIOS_KB        ;CONTINUE WITH BIOS ROUTINE
  1093. INSERT_KEY:
  1094.         STI            ;INTERRUPTS BACK ON
  1095.         MOV    BX,BUFF_NEXT    ;GET ADDRESS OF NEXT BYTE
  1096.         CMP    BX,BUFF_LAST    ;AT END OF BUFFER YET?
  1097.         JL    GET_A_KEY    ;IF NOT, GET THE NEXT ONE
  1098.         MOV    SEND_KEYS,0    ;WHEN DONE, TURN OFF SEND SWITCH
  1099. GET_A_KEY:
  1100.         MOV    AL,CS:[BX]    ;GET THE NEXT KEY CODE
  1101.         CMP    AL,10        ;IS IT A LINE FEED?
  1102.         JNE    NOT_LF        ;DONT RETURN THE LINE FEEDS
  1103.         INC    BUFF_NEXT    ;SKIP TO NEXT KEY
  1104.         JMP    INSERT_KEY
  1105. NOT_LF:
  1106.         CMP    AH,1        ;REQUEST FOR STATUS ONLY?
  1107.         JE    RETURN_STATUS    ;IF YES, RETURN STATUS ONLY
  1108.         CMP    AH,0        ;REQUEST TO GET THE NEXT KEY
  1109.         JNE    BIOS_KB        ;IF NOT, IGNORE THIS FUNCTION
  1110.         INC    BX        ;REMOVE THIS KEY FROM OUR BUFFER
  1111.         MOV    BUFF_NEXT,BX    ;SAVE THE POINTER TO NEXT KEY
  1112. RETURN_STATUS:
  1113.         OR    BL,1        ;CLEAR ZERO FLAG TO INDICATE A
  1114.         POP    BX        ;KEY IS AVAILIABLE
  1115.         RET    2        ;RETURN WITH THESE FLAGS
  1116. FILE_INSERT_KEY:
  1117.         STI            ;INTERRUPTS BACK ON
  1118.         MOV    BX,FILE_BUFF_NEXT    ;GET ADDRESS OF NEXT BYTE
  1119.         CMP    BX,FILE_BUFF_LAST    ;AT END OF BUFFER YET?
  1120.         JL    FILE_GET_A_KEY    ;IF NOT, GET THE NEXT ONE
  1121.         MOV    FILE_SEND_KEYS,0    ;WHEN DONE, TURN OFF SEND SWITCH
  1122. FILE_GET_A_KEY:
  1123.         MOV    AL,CS:[BX]    ;GET THE NEXT KEY CODE
  1124.         CMP    AL,10        ;IS IT A LINE FEED?
  1125.         JNE    FILE_NOT_LF        ;DONT RETURN THE LINE FEEDS
  1126.         INC    FILE_BUFF_NEXT    ;SKIP TO NEXT KEY
  1127.         JMP    FILE_INSERT_KEY
  1128. FILE_NOT_LF:
  1129.         CMP    AH,1        ;REQUEST FOR STATUS ONLY?
  1130.         JE    FILE_RETURN_STATUS    ;IF YES, RETURN STATUS ONLY
  1131.         CMP    AH,0        ;REQUEST TO GET THE NEXT KEY
  1132.         JNE    BIOS_KB        ;IF NOT, IGNORE THIS FUNCTION
  1133.         INC    BX        ;REMOVE THIS KEY FROM OUR BUFFER
  1134.         MOV    FILE_BUFF_NEXT,BX    ;SAVE THE POINTER TO NEXT KEY
  1135. FILE_RETURN_STATUS:
  1136.         OR    BL,1        ;CLEAR ZERO FLAG TO INDICATE A
  1137.         POP    BX        ;KEY IS AVAILIABLE
  1138.         RET    2        ;RETURN WITH THESE FLAGS
  1139. NEWINT16    ENDP
  1140. ;---------------------------------------------------------------------;
  1141. ; INTERRUPT 21 ROUTINE.  THIS ROUTINE IS USED TO MONITOR DOS FUNCTION ;
  1142. ; CALLS. IF THE BUFFER NEEDS TO BE FLUSHED, IT WIL BE DONE HERE.      ;
  1143. ;---------------------------------------------------------------------;
  1144. NEWINT21    PROC    FAR
  1145.         ASSUME    DS:NOTHING, ES:NOTHING
  1146.         STI
  1147.         OR    AH,AH        ;DOING FUNCTION ZERO?
  1148.         JNE    NOT_ZERO
  1149.         MOV    AH,4CH        ;IF YES, CHANGE IT TO A 4CH
  1150. NOT_ZERO:
  1151.         OR    BUSY_FLAGS,00000001B    ;SET DOS BUSY BIT
  1152.         MOV    DOS_STAT,AH
  1153.         PUSHF            ;SIMULATE AN INTERRUPT
  1154.         CALL    OLDINT21    ;DO THE DOS FUNCTION
  1155.         PUSHF            ;SAVE THE RESULT FLAGS
  1156.         AND    BUSY_FLAGS,11111110B    ;CLEAR DOS BUSY BIT
  1157.         CMP    WRIT_FILE,1    ;ANYTHING TO WRITE TO DISK?
  1158.         JNE    NO_WRITE    ;IF NOT JUST RETURN
  1159.         CALL    WRITE_TO_FILE    ;SAFE TO ACCESS DISK NOW
  1160. NO_WRITE:
  1161.         POPF            ;RECOVER DOS RESULT FLAGS
  1162.         RET    2        ;RETURN WITH DOS RESULT FLAGS
  1163. NEWINT21    ENDP
  1164. ;---------------------------------------------------------------------;
  1165. ; NEW INTERRUPT 24H (CRITICAL DOS ERROR).  THIS INTERRUPT IS ONLY IN  ;
  1166. ; EFFECT ONLY DURING A WRITE SCREEN.  IT IS REQUIRED TO SUPPRESS THE  ;
  1167. ; 'ABORT, RETRY, IGNORE' MESSAGE.  ALL FATAL DISK ERRORS ARE IGNORED. ;
  1168. ;---------------------------------------------------------------------;
  1169. NEWINT24    PROC    FAR
  1170.         ASSUME    CS:CSEG, DS:NOTHING, ES:NOTHING
  1171.         STI            ;TURN INTERRUPTS BACK ON
  1172.         INC     ERR_STAT    ;SET THE ERROR FLAG
  1173.          XOR    AL,AL        ;TELLS DOS TO IGNORE THE ERROR
  1174.         IRET            ;THATS ALL WE DO HERE
  1175. NEWINT24    ENDP
  1176.  
  1177. ;--------------------------------------------------------------------;
  1178. ; HERE IS THE CODE USED TO INITIALIZE SNIPPER.                       ;
  1179. ;--------------------------------------------------------------------;
  1180.         ASSUME    CS:CSEG, DS:CSEG, ES:CSEG
  1181. INITIALIZE:
  1182.         LEA    DX,COPYRIGHT
  1183.         MOV    AH,9        ;DOS DISPLAY STRING SERVICE
  1184.         INT    21H        ;DISPLAY TITLE MESSAGE
  1185. ; SEARCH FOR AN PREVIOUSLY INSTALLED COPY OF SNIPPER
  1186.         NOT    BYTE PTR START    ;MODIFY TO AVOID FASLE MATCH
  1187.         XOR    BX,BX        ;START SEARCH AT SEGMENT ZERO
  1188.         MOV    AX,CS        ;COMPARE TO THIS CODE SEGMENT
  1189. NEXT_SEGMENT:
  1190.         INC    BX        ;LOOK AT NEXT SEGMENT
  1191.         CMP    AX,BX        ;UNTIL REACHING THIS CODE SEG
  1192.         MOV    ES,BX
  1193.         JE    NOT_INSTALLED
  1194.         LEA    SI,START    ;SETUP TO COMPARE STRINGS
  1195.         MOV    DI,SI
  1196.         MOV    CX,16        ;16 BYTES MUST MATCH
  1197.         REP    CMPSB        ;COMPARE DS:SI TO ES:DI
  1198.         OR    CX,CX        ;DID THE STRINGS MATCH?
  1199.         JNE    NEXT_SEGMENT    ;IF NO MATCH, TRY NEXT SEGMENT
  1200.         LEA    DX,INSTALLED_MSG
  1201.         JMP    SHORT ERR_EXIT
  1202. NOT_INSTALLED:
  1203.         MOV    AH,30H
  1204.         INT    21H        ;GET DOS VERSION NUMBER
  1205.         CMP    AL,2        ;IS IT HIGHER THAN 2.0?
  1206.         JNB    VER_OK        ;IF YES, PROCEED
  1207.         LEA    DX,BAD_DOS_MSG
  1208. ERR_EXIT:    
  1209.         MOV    AH,9        ;DOS DISPLAY STRING SERVICE
  1210.         INT    21H        ;DISPLAY ERRER MESSAGE
  1211.         RET            ;RETURN TO DOS
  1212. EXIT_NON_TSR:
  1213.         MOV    AH,4CH
  1214.         INT    21H
  1215. VER_OK:
  1216.         INC    SI        ;POINT TO FIRST PARAMETER
  1217.         MOV    SI,81H        ;POINT TO PARAMETER AREA
  1218.         CALL    GET_PARAM    ;GET FIRST PARAMETER (ROWS)
  1219.         PUSH    AX        ;SAVE THE ROW COUNT
  1220.         CALL    GET_PARAM    ;GET SECOND PARAMETER (COLUMNS)
  1221.         ADD    AX,2        ;ADD SPACE FOR CR AND LF
  1222.         POP    BX        ;GET BACK FIRST PARAMETER
  1223.         MUL    BX        ;PRODUCT OF ROWS AND COLUMNS
  1224.         OR    AX,AX        ;WAS ANYTHING ENTERED?
  1225.         JE    NO_PARAMS    ;IF NOT, USE DEFAULT VALUE
  1226.         CMP    AX,10000    ;MAXIMUM BUFFER IS 10000 BYTES
  1227.         JLE    SIZE_IS_OK
  1228.         MOV    AX,10000
  1229. SIZE_IS_OK:
  1230.         ADD    AX,BUFF_START
  1231.         MOV    BUFF_END,AX    ;SET THE NEW BUFFER SIZE
  1232. NO_PARAMS:
  1233.         MOV    AX,BIOS_SEG    ;LOOK AT BIOS DATA AREA
  1234.         MOV    ES,AX
  1235.         ASSUME    ES:BIOS_SEG
  1236.         CMP    ROWS,0        ;IS NUMBER OF ROWS ENTERED HERE
  1237.         JNE    MUST_BE_EGA    ;IF YES, AN EGA MAY BE PRESENT
  1238.         MOV    ROWS,24        ;IF NOT EGA, MUST BE 24 ROWS
  1239. MUST_BE_EGA:
  1240.         ASSUME    ES:NOTHING
  1241.                MOV    AX,3509H    ;GET KEYBOARD BREAK VECTOR
  1242.         INT    21H
  1243.         MOV    WORD PTR [OLDINT09],  BX  ;SAVE SEGMENT
  1244.         MOV    WORD PTR [OLDINT09+2],ES  ;SAVE OFFSET
  1245.         MOV    DX, OFFSET NEWINT09
  1246.         MOV    AX, 2509H
  1247.         INT    21H        ;DOS FUNCTION TO CHANGE VECTOR
  1248.                MOV    AX,3513H    ;GET BIOS DISK INTERRUPT VECTOR
  1249.         INT    21H
  1250.         MOV    WORD PTR [OLDINT13],  BX  ;SAVE SEGMENT
  1251.         MOV    WORD PTR [OLDINT13+2],ES  ;SAVE OFFSET
  1252.         MOV    DX, OFFSET NEWINT13
  1253.         MOV    AX, 2513H
  1254.         INT    21H        ;DOS FUNCTION TO CHANGE VECTOR
  1255.                MOV    AX,3516H    ;GET KEYBOARD INPUT VECTOR
  1256.         INT    21H
  1257.         MOV    WORD PTR [OLDINT16],  BX  ;SAVE SEGMENT
  1258.         MOV    WORD PTR [OLDINT16+2],ES  ;SAVE OFFSET
  1259.         MOV    DX, OFFSET NEWINT16
  1260.         MOV    AX, 2516H
  1261.         INT    21H        ;DOS FUNCTION TO CHANGE VECTOR
  1262.                MOV    AX,3521H    ;GET DOS FUNCTION VECTOR
  1263.         INT    21H
  1264.         MOV    WORD PTR [OLDINT21],  BX
  1265.         MOV    WORD PTR [OLDINT21+2],ES
  1266.         MOV    DX, OFFSET NEWINT21
  1267.         MOV    AX, 2521H
  1268.         INT    21H        ;DOS FUNCTION TO CHANGE VECTOR
  1269.         CALL    GET_PARAM
  1270. ;--------------------------------------------------------------------;
  1271. ; DEALLOCATE OUR COPY OF THE ENVIORNMENT.                            ;
  1272. ; EXIT USING INT 27H. LEAVE CODE AND SPACE FOR BUFFER RESIDENT.      ;
  1273. ;--------------------------------------------------------------------;
  1274.         MOV    AX,DS:[002CH]    ;GET SEGMENT OF ENVIORNMENT
  1275.         MOV    ES,AX        ;PUT IT INTO ES
  1276.         MOV    AH,49H        ;RELEASE ALLOCATED MEMORY
  1277.         INT    21H
  1278.         MOV    DX,FILE_BUFF_END;LEAVE THIS MUCH RESIDENT
  1279.         INT    27H        ;TEMINATE AND STAY RESIDENT
  1280. ;---------------------------------------------------------;
  1281. ; GET_PARAM RETRIEVES AN INTEGER FROM THE COMMAND LINE.   ;
  1282. ;---------------------------------------------------------;
  1283. GET_PARAM:    
  1284.         XOR    AX,AX        ;CLEAR AX FOR TOTAL
  1285. GET_DIGIT:    
  1286.         MOV    BL,[SI]        ;GET CHARACTER INTO BL
  1287.         CMP    BL,0DH        ;IS IT THE LAST ONE?
  1288.         JE    DONE
  1289.         INC    SI        ;POINT TO NEXT CHARACTER
  1290.         CMP    BL,","        ;IS IT THE DELIMITER?
  1291.         JE    DONE
  1292.         CMP    BL,"/"        ;IS IT THE DELIMITER?
  1293.         JE    GET_THE_PATH
  1294.         SUB    BL,30H        ;CONVERT ASCII TO INTEGER
  1295.         JB    GET_DIGIT    ;IS IT A VALID DIGIT
  1296.         CMP    BL,9
  1297.         JA    GET_DIGIT    ;IF NOT VALID, JUST SKIP IT
  1298.         MOV    BH,10        ;TIMES 10 FOR NEXT DIGIT
  1299.         MUL    BH        ;MULTIPLY SUM AND ADD THIS DIGIT
  1300.         ADD    AL,BL        ;ADD DIGIT TO SUM
  1301.         JMP    GET_DIGIT    ;READ ALL CHARACTERS ON LINE
  1302. GET_THE_PATH:
  1303.         MOV    BL,[SI]
  1304.         CMP    BL,50H
  1305.         JE    PATH_FLAG_OK
  1306.         CMP    BL,70H
  1307.         JNE    DONE
  1308. PATH_FLAG_OK:
  1309.         INC    SI
  1310.         MOV    BL,[SI]
  1311.         CMP    BL,3DH
  1312.         JNE    DONE
  1313.         INC    SI
  1314.         LEA    DI,FILE_PATH
  1315. GET_THE_PATH_LOOP:
  1316.         MOV    BL,[SI]
  1317.         CMP    BL,0DH
  1318.         JE    PATH_DONE
  1319.         MOV    [DI],BL
  1320.         INC    SI
  1321.         INC    DI
  1322.         JMP    GET_THE_PATH_LOOP
  1323. PATH_DONE:
  1324.         MOV    BYTE PTR[DI],5CH
  1325. DONE:        
  1326.         RET
  1327. CSEG        ENDS
  1328.         END    START
  1329.